/* eslint-disable */
// ==UserScript==
// @name         PHP define to Typescript definition
// @namespace    https://i.zapic.moe/
// @version      0.1
// @description  从文档复制API响应数据的Typescript接口定义
// @author       Zapic
// @match        https://developer.discuz.chat/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=discuz.chat
// @grant        none
// ==/UserScript==

(function () {
  "use strict";
  const propertyToStruct = node => {
    const struct = {};
    struct.name = node.querySelector(".name").innerText.slice(0, -1);
    const inner = node.querySelector(
      ".inner:not(.description,.enums,.json-formatter-row)"
    );
    if (!inner) {
      struct.description = node.querySelector(".inner.description")?.innerText;
      struct.type = node.querySelector(".type").innerText;
      if (struct.type == "integer") {
        struct.type = "number";
      }
      const enums = node.querySelector(".inner.enums");
      if (enums) {
        struct.enum = Array.from(
          enums.querySelectorAll(".json-formatter-row:not(.inner)")
        ).map(v => v.firstChild.lastChild.innerText);
      }
      return struct;
    }
    struct.description = inner.querySelector(".description")?.innerText;
    struct.children = Array.from(inner.children)
      .filter(v => v.className == "property")
      .map(v => {
        return propertyToStruct(v);
      });
    return struct;
  };
  const genTab = level => "  ".repeat(level);
  const parse = node => {
    return parseNode(node, 0);
  };
  const parseChild = (children, level) => {
    const tab = genTab(level);
    return children
      .map(child => {
        if (child.type) {
          const type = child.enum ? child.enum.join(" | ") : child.type;
          return (
            tab +
            child.name +
            ": " +
            type +
            ";" +
            (child.description ? " // " + child.description : "")
          );
        }
        return parseNode(child, level);
      })
      .join("\n");
  };
  const parseNode = (node, level) => {
    const tab = genTab(level);
    let result = tab + "// " + node.description + "\n";
    if (level == 0) {
      result += "interface " + node.name + " {\n";
    } else {
      result += tab + node.name + ": {\n";
    }
    if (node.children) {
      result += parseChild(node.children, level + 1);
    }
    result += "\n" + tab + "}";
    return result;
  };
  const base = Array.from(
    document.querySelectorAll(".swagger-schema .property>.name")
  ).find(v => v.innerText == "Data:").parentElement;
  if (!base) {
    console.error("Cannot find Data Root");
    return;
  }

  document
    .querySelectorAll(".json-schema-view.collapsed .toggle-handle")
    .forEach(v => v.click());
  document
    .querySelectorAll(".json-schema-view .json-formatter-toggler")
    .forEach(v => v.click());
  setTimeout(() => {
    const result = propertyToStruct(base);
    const definition = parse(result);
    console.log(definition);
  }, 500);
})();
